# 查看日志
#cat /tmp/deploy-*.log
#查看最新日志
#elvish deploy.elv logs

# 运行脚本
# 普通模式:
#elvish deploy.elv
# 调试模式:
#DEBUG=1 elvish deploy.elv

# 插件依赖
#sudo apt install -y git rsync linkchecker curl tar

# 检查文件权限并设为可执行
#chmod +x deploy.elv


#脚本正文

#!/usr/bin/env elvish

use str
use path

# ---------- 配置项 ----------
var config = [
  &log_file=(printf "/tmp/deploy-%s.log" (date +"%Y%m%d-%H%M%S"))
  &source_dir=(path:abs ~/git/app.mogan)
  &deploy_dir=(path:abs ~/git/mogan.app)
  &site_url="https://mogan.app"
  &backup_dir=(path:abs ~/git/site-backups-mogan)
  &debug=(not-eq $E:DEBUG "")
]

# ---------- 日志系统 ----------
fn write-log {|level msg|
  try {
    var ts = (date +%Y-%m-%dT%H:%M:%S)
    var log_line = (printf "[%s][%s] %s\n" $ts $level $msg)
    
    # 同时输出到终端和文件
    echo $log_line
    echo $log_line >> $config[log_file]
    
    # 调试模式显示日志文件路径
    if $config[debug] {
      echo "Log written to: "$config[log_file] >&2
    }
  } catch e {
    echo "Warning: Failed to write log: "$e >&2
  }
}

fn info {|msg| write-log INFO $msg }
fn error {|msg| write-log ERROR $msg; exit 1 }

# ---------- 备份功能 ----------
fn save-backup {
  info "📦 保存当前版本..."
  var backup_dir = $config[backup_dir]/latest
  rm -rf $backup_dir
  mkdir -p $backup_dir
  rsync -a --delete $config[deploy_dir]/ $backup_dir/
}

fn restore-backup {
  info "⏪ 还原上一版本..."
  var backup_dir = $config[backup_dir]/latest
  if (not (path:is-dir $backup_dir)) {
    error "没有可用的备份"
  }
  
  try {
    # 排除.git目录，避免破坏git仓库
    rsync -a --delete --exclude '.git' $backup_dir/ $config[deploy_dir]/
    
    # 强制提交还原的更改
    cd $config[deploy_dir]
    git add -A
    
    # 检查是否有实际变更
    var has_changes = (not ?(git diff --cached --quiet))
    if $has_changes {
      git commit -m "回滚到上一版本 [$(date -Iseconds)]"
      git push -f origin main
      info "✅ 还原完成"
    } else {
      info "没有需要还原的更改"
    }
  } catch e {
    error "还原失败，请手动检查状态"
  }
}

fn deploy-site {
  try {
    info "🔄 重置部署目录..."
    git -C $config[deploy_dir] fetch origin
    git -C $config[deploy_dir] reset --hard origin/main
    
    info "📦 复制网站文件..."
    save-backup
    rsync -a --delete --exclude '.git' --exclude '.github' $config[source_dir]/website/ $config[deploy_dir]/
    
    info "📤 提交更改..."
    git -C $config[deploy_dir] add -A
    git -C $config[deploy_dir] commit -m "部署更新"
    git -C $config[deploy_dir] push origin main
    
    # 添加等待GitHub Pages部署的提示
    info "⏳ 等待GitHub Pages部署生效（30s）..."
    sleep 30
    
    # 尝试清理GitHub Pages缓存
    info "🧹 清理缓存..."
    curl -X PURGE $config[site_url]
  } catch e {
    error "部署失败: "$e
  }
}

# ---------- 核心功能 ----------
fn pull-source {
  try {
    info "🔨 构建网站..."
    rm -rf $config[source_dir]/website
    cd $config[source_dir]
    ./bin/build_website
    
    info "✓ 网站构建完成"
  } catch e {
    error "源码处理失败: "$e
  }
}

# ---------- 检测功能 ----------
fn check-accessibility {
  info "🌐 检查网站可访问性..."
  try {
    # 将输出分开保存
    var temp_file = (mktemp)
    # 添加no-cache头，避免获取缓存内容
    var status = (curl -sL -H "Cache-Control: no-cache" -w "%{http_code}" $config[site_url] -o $temp_file)
    rm -f $temp_file
    
    if (!=s $status "200") {
      error "网站响应状态码异常: "$status
    }
    info "✓ 网站访问正常"
  } catch e {
    error "网站访问失败"
  }
}

fn check-dead-links {
  info "🔍 检查死链..."
  var temp_file = (mktemp)
  var success = $false
  
  try {
    info "开始检查死链，这可能需要几分钟..."
    linkchecker --no-warnings --no-status $config[site_url] | tee $temp_file
    
    if ?(grep -q "0 errors found" $temp_file) {
      set success = $true
      info "✓ 死链检测通过"
    } elif ?(grep -q "Error: 404" $temp_file) {
      info "发现404错误:"
      grep -A 1 "Error: 404" $temp_file | sed 's/^/  /'
      error "检测到404死链"
    } else {
      error "死链检测未正常完成"
    }
    
  } finally {
    rm -f $temp_file
    # 仅在检测异常中断时显示跳过信息
    if (not $success) {
      info "Note: 死链检测跳过 - 执行异常"
    }
  }
}

fn check-seo {
  info "📊 检查SEO基础项..."
  var temp_file = (mktemp)
  
  try {
    # 获取页面内容
    curl -sL $config[site_url] > $temp_file
    
    var has_title = ?(grep -qi '<title>[^<]*</title>' $temp_file)
    var has_desc = ?(grep -qi '<meta[^>]*name="description"[^>]*content="[^"]*"' $temp_file)
    
    # 清理临时文件
    rm -f $temp_file
    
    # 整理检测结果
    if (not $has_title) {
      error "缺少网页标题"
    }
    if (not $has_desc) {
      error "缺少网页描述"
    }
    
    # 如果检测都通过了
    info "✓ SEO检查通过（标题和描述都已找到）"
  } catch e {
    rm -f $temp_file
    error "SEO检测失败: "$e
  }
}

fn check-site {
  info "🔎 开始网站检测..."
  
  try {
    # 1. 基础检查
    check-accessibility
    check-seo
    
    # 2. 死链检查（发现404时才回滚）
    try {
      check-dead-links
    } catch e {
      if (str:contains (to-string $e) "检测到死链") {
        info "🔄 开始还原..."
        restore-backup
        error "发现404死链，已还原"
      }
    }
    
    info "✅ 所有检测通过"
  } catch e {
    info "❌ 检测失败，开始还原..."
    restore-backup
    error "检测未通过，已还原"
  }
}

# ---------- 日志功能 ----------
fn show-latest-log {
  var logs = []
  try {
    set logs = [(put /tmp/deploy-*.log)]
  } catch e {
  }
  
  if (== (count $logs) 0) {
    echo "没有找到部署日志文件"
    exit 1
  }
  
  var latest = $logs[(- (count $logs) 1)]
  echo "显示最新日志: "$latest
  try {
    cat $latest
  } catch e {
    echo "无法读取日志文件: "$latest
    exit 1
  }
}

# ---------- 主函数 ----------
fn main {|@args|
  if (and (> (count $args) 0) (==s $args[0] "logs")) {
    show-latest-log
    return
  }
  
  info "🚀 开始部署"
  pull-source
  deploy-site
  check-site
  info "✨ 部署完成"
}

# 执行主函数
main $@args
